#pragma once

#include "Log.hpp"
#include "Socket.hpp"
#include <signal.h>
#include <functional>

using func_t = std::function<std::string (std::string&)>;

class TcpServer
{
public:
    TcpServer(uint16_t port, func_t callback):m_port(port), m_callback(callback)
    {}

    bool InitServer()
    {
        m_listensock.Socket();
        m_listensock.Bind(m_port);
        m_listensock.Listen();
        log(INFO,"init tcpserver success...");
        return true;
    }

    void Start()
    {
        signal(SIGCHLD, SIG_IGN);
        signal(SIGPIPE, SIG_IGN);
        while(true)
        {
            std::string clientip;
            uint16_t clientport;
            int server_sock = m_listensock.Accept(&clientip, &clientport);
            std::cout << server_sock << std::endl;
            if(server_sock < 0)
            {
                continue;
            }

            log(INFO, "accept a new link, sockfd: %d, clientip: %s, clientport: %d", server_sock, clientip.c_str(), clientport);
            // 提供服务
            pid_t id = fork();
            if(id == 0)
            {
                m_listensock.Close();
                std::string inbuffer_stream;
                // 子进程提供服务 -- 数据计算
                while(true)
                {
                    char buffer[128];
                    size_t n = read(server_sock, buffer, sizeof(buffer));
                    if(n > 0)
                    {
                        buffer[n] = 0;
                        inbuffer_stream += buffer;

                        log(DEBUG, "debug:\n%s", inbuffer_stream.c_str());
                        
                        std::string info = m_callback(inbuffer_stream);
                        if(info.empty()) continue;
                        write(server_sock, info.c_str(), info.size());

                        // 一次可以解析多个报文
                        // while(true)
                        // {
                        //     std::string info = m_callback(inbuffer_stream);
                        //     log(DEBUG, "debug, response: \n%s", info.c_str());
                        //     log(DEBUG, "debug: \n%s", inbuffer_stream.c_str());
                        //     if(info.empty()) break;
                        //     write(server_sock, info.c_str(), info.size());
                        // }
                    }
                    else if(n == 0)
                    {
                        break;
                    }
                    else 
                        break;
                }
                exit(0);
            }
            close(server_sock);
        }
    }

    ~TcpServer(){}
private:
    uint16_t m_port;
    Sock m_listensock;
    func_t m_callback;
};